package com.bdq.user.domain.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.bdq.common.config.base.DefaultAvatarConfig;
import com.bdq.common.config.base.StaticDomainConfig;
import com.bdq.common.enums.*;
import com.bdq.common.exception.ServerException;
import com.bdq.common.utils.BaseConfigUtil;
import com.bdq.common.utils.StaticFileUtil;
import com.bdq.common.utils.TokenUtil;
import com.bdq.user.domain.model.agg.UserAgg;
import com.bdq.user.domain.model.dto.*;
import com.bdq.user.domain.model.dto.req.UserUpdateReqDTO;
import com.bdq.user.domain.model.dto.req.ViewRegionLevelUpdateReqDTO;
import com.bdq.user.domain.model.value.UserLocationValue;
import com.bdq.user.domain.model.value.UserRoleCertificationValue;
import com.bdq.user.domain.service.UserDomainService;
import com.bdq.user.infrastructure.cache.UserCache;
import com.bdq.user.domain.model.dto.LoginDomainDTO;
import com.bdq.user.infrastructure.persistence.mysql.pojo.User;
import com.bdq.user.infrastructure.persistence.mysql.pojo.UserLocation;
import com.bdq.user.infrastructure.persistence.mysql.pojo.UserRoleCertification;
import com.bdq.user.infrastructure.persistence.mysql.service.UserFollowService;
import com.bdq.user.infrastructure.persistence.mysql.service.UserLocationService;
import com.bdq.user.infrastructure.persistence.mysql.service.UserRoleCertificationService;
import com.bdq.user.infrastructure.persistence.mysql.service.UserService;
import com.bdq.user.infrastructure.util.TencentImUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author malei
 * @date 2024-05-04 09:08
 */
@Service
public class UserDomainServiceImpl implements UserDomainService {

    @Resource
    private UserService userService;

    @Resource
    private UserLocationService userLocationService;

    @Resource
    private UserRoleCertificationService userRoleCertificationService;

    @Resource
    private UserFollowService userFollowService;

    @Override
    public void userAggFill(String userMobile, UserAgg userAgg) {
        User user = userService.getByUserMobile(userMobile);
        if (Objects.isNull(user)) {
            throw new ServerException("用户不存在");
        }
        BeanUtils.copyProperties(user, userAgg);

        UserLocation userLocation = userLocationService.getByUserId(user.getId());
        if (Objects.nonNull(userLocation)) {
            userAgg.setUserLocation(Convert.convert(UserLocationValue.class, userLocation));
        }

        UserRoleCertification userRoleCertification = userRoleCertificationService.getByUserId(user.getId());
        if (Objects.nonNull(userRoleCertification)) {
            userAgg.setUserRoleCertification(Convert.convert(UserRoleCertificationValue.class, userRoleCertification));
        }
    }

    @Override
    public LoginDomainDTO login(UserAgg userAgg) {
        // 1 校验
        String loginVerifyCode = UserCache.getLoginVerifyCode(userAgg.getUserMobile());
        if (StrUtil.isBlank(loginVerifyCode)) {
            throw new ServerException("验证码已过期");
        }
        if (!userAgg.getLoginVerifyCode().equals(loginVerifyCode)) {
            throw new ServerException("请输入正确验证码");
        }

        // 2 用户不存在创建用户
        User user = userService.getByUserMobile(userAgg.getUserMobile());
        if (Objects.isNull(user)) {
            User userSaveObj = new User();
            userSaveObj.setAvatar(BaseConfigUtil.getConfig(BaseConfigEnum.STATIC_DOMAIN.getName(), DefaultAvatarConfig.class).getAvatar());
            userSaveObj.setUserMobile(userAgg.getUserMobile());
            userService.save(userSaveObj);
            // 腾讯云IM 注册
            TencentImUtil.singleAccountImport(userSaveObj.getId(), "", "");
        }

        // 3 获取用户聚合
        userAggFill(userAgg.getUserMobile(), userAgg);

        // 4 生成Token
        String token = TokenUtil.createToken(userAgg.getUserMobile());

        // 5 保存Token
        UserCache.saveToken(userAgg.getUserMobile(), token);

        // 6 保存用户上下文
        UserCache.saveUserContext(userAgg.getUserMobile(), JSON.toJSONString(userAgg));

        // 6 返回
        LoginDomainDTO loginDomainDTO = new LoginDomainDTO();
        loginDomainDTO.setToken(token);
        return loginDomainDTO;
    }

    @Override
    public Boolean logout(String userMobile) {
        UserCache.deleteToken(userMobile);
        return true;
    }

    @Override
    public UserDomainDTO userDetail(UserAgg userAgg) {
        UserDomainDTO userDomainDTO = Convert.convert(UserDomainDTO.class, userAgg);
        userDomainDTO.setAvatar(StaticFileUtil.domainConcat(userAgg.getAvatar()));

        // 1 生日
        if (Objects.nonNull(userAgg.getBirthday())) {
            UserBirthdayDomainDTO userBirthdayDomainDTO = new UserBirthdayDomainDTO();
            userBirthdayDomainDTO.setYear(userAgg.getBirthday().getYear());
            userBirthdayDomainDTO.setMonth(userAgg.getBirthday().getMonthValue());
            userBirthdayDomainDTO.setDay(userAgg.getBirthday().getDayOfMonth());
            userDomainDTO.setUserBirthday(userBirthdayDomainDTO);
        }

        // 2 位置
        if (Objects.nonNull(userAgg.getUserLocation())) {
            UserLocationValue userLocation = userAgg.getUserLocation();
            userDomainDTO.setLocation(userLocation.getProvinceName().concat("·").concat(userLocation.getCityName()).concat("·")
                    .concat(userLocation.getDistrictName()).concat("·").concat(userLocation.getVillageName()));
        }

        // 3 用户认证
        if (UserRoleEnum.BUSINESS.getCode() == userDomainDTO.getRole() || UserRoleEnum.COMMUNITY_ORGANIZATION.getCode() == userDomainDTO.getRole()) {
            UserRoleCertificationValue userRoleCertification = userAgg.getUserRoleCertification();
            UserRoleCertificationDomainDTO userRoleCertificationDomainDTO = new UserRoleCertificationDomainDTO();
            userRoleCertificationDomainDTO.setCertificationName(userRoleCertification.getCertificationName());
            userRoleCertificationDomainDTO.setStatus(userRoleCertification.getStatus());
            List<String> materialPictureList = new ArrayList<>();
            List<String> materialPictureListNoDomain = StrUtil.split(userRoleCertification.getMaterialPictures(), ',');
            for (String pic : materialPictureListNoDomain) {
                materialPictureList.add(StaticFileUtil.domainConcat(pic));
            }
            userRoleCertificationDomainDTO.setMaterialPictureList(materialPictureList);
            userDomainDTO.setUserRoleCertification(userRoleCertificationDomainDTO);
        }

        // 4 用户角色文本
        if (UserRoleEnum.INDIVIDUAL.getCode() == userDomainDTO.getRole()) {
            if (Objects.nonNull(userAgg.getUserLocation())) {
                userDomainDTO.setCertificationName(userAgg.getUserLocation().getDistrictName().concat("·").concat(userAgg.getUserLocation().getVillageName()));
            }
        }else {
            userDomainDTO.setCertificationName(userAgg.getUserRoleCertification().getCertificationName());
        }
        return userDomainDTO;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean userUpdate(UserUpdateReqDTO dto, UserAgg userAgg) {
        User user = new User();
        user.setId(userAgg.getId());
        user.setNickName(dto.getNickName());
        user.setIntroduction(dto.getIntroduction());
        // 头像
        if (StrUtil.isNotBlank(dto.getAvatar())) {
            user.setAvatar(StaticFileUtil.domainCut(dto.getAvatar()));
        }
        // 性别
        if (Objects.nonNull(dto.getSex())) {
            user.setSex(dto.getSex());
        }
        // 生日 年龄
        if (Objects.nonNull(dto.getBirthday())) {
            user.setBirthday(dto.getBirthday());
            user.setAge(LocalDate.now().getYear() - dto.getBirthday().getYear());
        }
        // 所在地
        if (Objects.nonNull(dto.getUserUpdateLocation())) {
            UserLocation userLocation = Convert.convert(UserLocation.class, dto.getUserUpdateLocation());
            if (Objects.nonNull(userAgg.getUserLocation())) {
                userLocation.setId(userAgg.getUserLocation().getId());
            }
            userLocation.setUserId(userAgg.getId());
            userLocationService.saveOrUpdate(userLocation);
            if (ViewRegionLevelEnum.VILLAGE.getCode() == userAgg.getViewRegionLevel()) {
                user.setViewRegionId(userLocation.getVillageId());
            }else if (ViewRegionLevelEnum.TOWNSHIP.getCode() == userAgg.getViewRegionLevel()) {
                user.setViewRegionId(userLocation.getTownshipId());
            }else if (ViewRegionLevelEnum.DISTRICT.getCode() == userAgg.getViewRegionLevel()) {
                user.setViewRegionId(userLocation.getDistrictId());
            }else if (ViewRegionLevelEnum.CITY.getCode() == userAgg.getViewRegionLevel()) {
                user.setViewRegionId(userLocation.getCityId());
            }else if (ViewRegionLevelEnum.PROVINCE.getCode() == userAgg.getViewRegionLevel()) {
                user.setViewRegionId(userLocation.getProvinceId());
            }
        }
        // 角色认证
        if (Objects.nonNull(dto.getUserUpdateRoleCertification())) {
            user.setRole(dto.getUserUpdateRoleCertification().getRole());
            UserRoleCertification userRoleCertification = new UserRoleCertification();
            if (Objects.nonNull(userAgg.getUserRoleCertification())) {
                userRoleCertification.setId(userAgg.getUserRoleCertification().getId());
            }
            userRoleCertification.setUserId(userAgg.getId());
            userRoleCertification.setCertificationName(dto.getUserUpdateRoleCertification().getCertificationName());
            userRoleCertification.setStatus(UserRoleCertificationStatus.APPROVED.getCode());
            List<String> materialPictures = new ArrayList<>();
            for (String pic : dto.getUserUpdateRoleCertification().getMaterialPictureList()) {
                materialPictures.add(StaticFileUtil.domainCut(pic));
            }
            userRoleCertification.setMaterialPictures(CollUtil.join(materialPictures, ","));
            userRoleCertificationService.saveOrUpdate(userRoleCertification);
        }
        // 更新
        userService.updateById(user);

        // 更新用户上下文
        userAggFill(userAgg.getUserMobile(), userAgg);
        UserCache.saveUserContext(userAgg.getUserMobile(), JSON.toJSONString(userAgg));

        // 更新IM信息
        TencentImUtil.singleAccountImport(userAgg.getId(), userAgg.getNickName(), StaticFileUtil.domainConcat(userAgg.getAvatar()));
        return true;
    }

    @Override
    public List<ViewRegionLevelDomainDTO> getViewRegionLevel(UserAgg userAgg) {
        UserLocationValue userLocation = userAgg.getUserLocation();
        if (Objects.isNull(userAgg)) {
            throw new ServerException("请先填写所在地");
        }
        List<ViewRegionLevelDomainDTO> domainDTOList = new ArrayList<>();

        // 本市
        ViewRegionLevelDomainDTO city = new ViewRegionLevelDomainDTO();
        city.setRegionName(userLocation.getCityName());
        city.setRegionLevel(ViewRegionLevelEnum.CITY.getCode());
        if (userAgg.getViewRegionLevel() == ViewRegionLevelEnum.CITY.getCode()) {
            city.setSelected(YesOrNoEnum.YES.getCode());
        }else {
            city.setSelected(YesOrNoEnum.NO.getCode());
        }
        domainDTOList.add(city);

        // 本区县
        ViewRegionLevelDomainDTO district = new ViewRegionLevelDomainDTO();
        district.setRegionName(userLocation.getDistrictName());
        district.setRegionLevel(ViewRegionLevelEnum.DISTRICT.getCode());
        if (userAgg.getViewRegionLevel() == ViewRegionLevelEnum.DISTRICT.getCode()) {
            district.setSelected(YesOrNoEnum.YES.getCode());
        }else {
            district.setSelected(YesOrNoEnum.NO.getCode());
        }
        domainDTOList.add(district);

        // 本乡镇街道
        ViewRegionLevelDomainDTO township = new ViewRegionLevelDomainDTO();
        township.setRegionName(userLocation.getTownshipName());
        township.setRegionLevel(ViewRegionLevelEnum.TOWNSHIP.getCode());
        if (userAgg.getViewRegionLevel() == ViewRegionLevelEnum.TOWNSHIP.getCode()) {
            township.setSelected(YesOrNoEnum.YES.getCode());
        }else {
            township.setSelected(YesOrNoEnum.NO.getCode());
        }
        domainDTOList.add(township);

        // 本村社区
        ViewRegionLevelDomainDTO village = new ViewRegionLevelDomainDTO();
        village.setRegionName(userLocation.getVillageName());
        village.setRegionLevel(ViewRegionLevelEnum.VILLAGE.getCode());
        if (userAgg.getViewRegionLevel() == ViewRegionLevelEnum.VILLAGE.getCode()) {
            village.setSelected(YesOrNoEnum.YES.getCode());
        }else {
            village.setSelected(YesOrNoEnum.NO.getCode());
        }
        domainDTOList.add(village);

        return domainDTOList;
    }

    @Override
    public Boolean updateViewRegionLevel(ViewRegionLevelUpdateReqDTO dto, UserAgg userAgg) {
        User userUpdateObj = new User();
        userUpdateObj.setId(userAgg.getId());
        userUpdateObj.setViewRegionLevel(dto.getRegionLevel());
        if (userUpdateObj.getViewRegionLevel() == ViewRegionLevelEnum.CITY.getCode()) {
            userUpdateObj.setViewRegionId(userAgg.getUserLocation().getCityId());
        }else if (userUpdateObj.getViewRegionLevel() == ViewRegionLevelEnum.DISTRICT.getCode()) {
            userUpdateObj.setViewRegionId(userAgg.getUserLocation().getDistrictId());
        }else if (userUpdateObj.getViewRegionLevel() == ViewRegionLevelEnum.TOWNSHIP.getCode()) {
            userUpdateObj.setViewRegionId(userAgg.getUserLocation().getTownshipId());
        }else if (userUpdateObj.getViewRegionLevel() == ViewRegionLevelEnum.VILLAGE.getCode()) {
            userUpdateObj.setViewRegionId(userAgg.getUserLocation().getVillageId());
        }
        userService.updateById(userUpdateObj);

        // 更新用户上下文
        userAggFill(userAgg.getUserMobile(), userAgg);
        UserCache.saveUserContext(userAgg.getUserMobile(), JSON.toJSONString(userAgg));
        return true;
    }

    @Override
    public UserFollowNumDomainDTO userFollowNumGet(Long userId) {
        UserFollowNumDomainDTO userFollowNumDomainDTO = new UserFollowNumDomainDTO();
        userFollowNumDomainDTO.setFollowerNum(formatFansCount(userFollowService.getFollowerNum(userId)));
        userFollowNumDomainDTO.setFollowedNum(formatFansCount(userFollowService.getFollowedNum(userId)));
        userFollowNumDomainDTO.setEachFollowedNum(formatFansCount(userFollowService.getEachFollowerNum(userId)));
        return userFollowNumDomainDTO;
    }

    /**
     * 粉丝数转字符串
     *
     * @param count
     * @return
     */
    public static String formatFansCount(Long count) {
        if (count == null) {
            return "0";
        }
        if (count < 10000) {
            return count.toString();
        } else if (count < 100000) {
            return String.format("%.1f万", count / 10000.0);
        } else if (count < 100000000) {
            return String.format("%d万", count / 10000);
        } else {
            return String.format("%.1f亿", count / 100000000.0);
        }
    }
}
